using System;
using System.Collections;
using System.Data;
using System.IO;
using DataSync.Models.AppSetting;
using DataSync.Properties;
using DataSync.Utilities;
using Microsoft.Win32;

namespace DataSync.Services.Common
{
    public class CommonService
    {
        public static int DetectExcelVersion()
        {
            var versionNumber = 0;
            var versionNumberList =
                new ArrayList(2)
                    {
                        //Excel 2003
                        11, 
                        //Excel 2007
                        12
                    };

            foreach (int version in versionNumberList)
            {
                //Detect installed version
                var registryKey = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\Office\" + version.ToString("N1"));
                if (registryKey == null)
                    continue;

                //Fetch executable file of detected version 
                var registeredPath = "Software\\Microsoft\\Office\\" + version.ToString("N1") + "\\Excel\\InstallRoot";
                registryKey = Registry.LocalMachine.OpenSubKey(registeredPath);
                if (registryKey == null)
                    continue;

                var executablePath = (string)registryKey.GetValue("Path");
                var executableFile = executablePath + "EXCEL.EXE";

                if (!File.Exists(executableFile))
                    continue;


                versionNumber = version;
                break;
            }

            return versionNumber;
        }

        public static FileInfo DetectSettingFile(string startUpPath)
        {
            var settingFound = true;
            var fileInfo = new FileInfo(startUpPath + @"\" + Resources.SettingFileName);

            if (!fileInfo.Exists)
            {
                settingFound = CreateSettingFile(fileInfo);
                fileInfo.Refresh();
            }

            return settingFound ? fileInfo : null;
        }

        public static bool CreateSettingFile(FileInfo fileInfo)
        {
            try
            {
                if (fileInfo == null)
                {
                    SaveLog(Resources.CreateSettingFile, Resources.MsgCreateSettingFileFailed);
                    return false;
                }

                if (fileInfo.Exists)
                    fileInfo.Delete();

                var settingList = AppSetting.GenearteAppSetting();
                var dataRow = settingList.Tables[0].NewRow();
                dataRow[Resources.SettingSynchronizeTime] = "21";
                dataRow[Resources.SettingSynchronizeFrequency] = "24";
                dataRow[Resources.SettingSendMailTime] = "22";
                dataRow[Resources.SettingSendMailFrequency] = "Sunday";
                dataRow[Resources.SettingEmployeeTime] = "20";

                settingList.Tables[0].Rows.Add(dataRow);
                settingList.WriteXml(fileInfo.FullName);

                SaveLog(Resources.OperationCreateSetting, Resources.MsgCreateSettingFileSuccess);
                return true;
            }
            catch (Exception exception)
            {
                SaveLog(Resources.OperationCreateSetting, exception.Message);
                return false;
            }
        }

        public static bool RetrieveSetting(
            string startUpPath, 
            ref int attendanceSyncTime, 
            ref int attendanceSyncFrequency,
            ref int mailSendTime,
            ref string mailSendFrequency,
            ref int employeeSyncTime)
        {
            var fileInfo = DetectSettingFile(startUpPath);

            if(fileInfo == null)
            {
                SaveLog(Resources.DetectSettingFile, Resources.MsgSettingFileMissing);
                return false;
            }

            if (!fileInfo.Exists)
            {
                SaveLog(Resources.DetectSettingFile, Resources.MsgSettingFileMissing);
                return false;
            }

            var settingList = AppSetting.GenearteAppSetting();
            settingList.ReadXml(fileInfo.FullName);
            if (settingList.Tables == null)
            {
                SaveLog(Resources.ParseSettingFile, Resources.MsgInvalidSettingFile);
                return false;
            }

            if(settingList.Tables.Count == 0)
            {
                SaveLog(Resources.ParseSettingFile, Resources.MsgInvalidSettingFile);
                return false;
            }

            if (settingList.Tables[0] == null)
            {
                SaveLog(Resources.ParseSettingFile, Resources.MsgInvalidSettingFile);
                return false;
            }

            if (settingList.Tables[0].Rows == null)
            {
                SaveLog(Resources.ParseSettingFile, Resources.MsgInvalidSettingFile);
                return false;
            }

            if (settingList.Tables[0].Rows.Count == 0)
            {
                SaveLog(Resources.ParseSettingFile, Resources.MsgInvalidSettingFile);
                return false;
            }

            foreach (DataRow dataRow in settingList.Tables[0].Rows)
            {
                if (dataRow == null)
                    continue;

                //Retrieve global parameters
                Int32.TryParse(dataRow[Resources.SettingSynchronizeTime].ToString(), out attendanceSyncTime);
                Int32.TryParse(dataRow[Resources.SettingSynchronizeFrequency].ToString(), out attendanceSyncFrequency);
                Int32.TryParse(dataRow[Resources.SettingSendMailTime].ToString(), out mailSendTime);
                mailSendFrequency = dataRow[Resources.SettingSendMailFrequency].ToString();
                Int32.TryParse(dataRow[Resources.SettingEmployeeTime].ToString(), out employeeSyncTime);

                return true;
            }

            return false;
        }

        public static bool SaveSetting(string startUpPath,
            int attendanceSyncTime,
            int attendanceSyncFrequency,
            ref DateTime attendanceSyncDate,
            int mailSendTime,
            ref DateTime mailSendSyncDate,
            string mailSendFrequency,
            int employeeSyncTime,
            ref DateTime employeeSyncDate)
        {
            try
            {
                var settingFile = startUpPath + @"\" + Resources.SettingFileName;
                var fileInfo = new FileInfo(settingFile);
                if (!fileInfo.Exists)
                {
                    SaveLog(Resources.DetectSettingFile, Resources.MsgSettingFileMissing);
                    return false;
                }

                var settingList = AppSetting.GenearteAppSetting();
                settingList.ReadXml(fileInfo.FullName);
                if (settingList.Tables == null)
                {
                    SaveLog(Resources.ParseSettingFile, Resources.MsgInvalidSettingFile);
                    return false;
                }

                if (settingList.Tables.Count == 0)
                {
                    SaveLog(Resources.ParseSettingFile, Resources.MsgInvalidSettingFile);
                    return false;
                }

                if (settingList.Tables[0] == null)
                {
                    SaveLog(Resources.ParseSettingFile, Resources.MsgInvalidSettingFile);
                    return false;
                }

                if (settingList.Tables[0].Rows == null)
                {
                    SaveLog(Resources.ParseSettingFile, Resources.MsgInvalidSettingFile);
                    return false;
                }

                settingList.Tables[0].Rows[0][Resources.SettingSynchronizeTime] = attendanceSyncTime;
                attendanceSyncDate =
                    DateTime.Parse(employeeSyncDate.Date.ToShortDateString() + " " + StringHelper.Right("00" + attendanceSyncTime, 2) + ":00");
                settingList.Tables[0].Rows[0][Resources.SettingSynchronizeFrequency] = attendanceSyncFrequency;
                settingList.Tables[0].Rows[0][Resources.SettingSendMailTime] = mailSendTime;
                mailSendSyncDate =
                    DateTime.Parse(mailSendSyncDate.Date.ToShortDateString() + " " + StringHelper.Right("00" + mailSendTime, 2) + ":00");
                settingList.Tables[0].Rows[0][Resources.SettingSendMailFrequency] = mailSendFrequency;
                settingList.Tables[0].Rows[0][Resources.SettingEmployeeTime] = employeeSyncTime;
                employeeSyncDate =
                    DateTime.Parse(employeeSyncDate.Date.ToShortDateString() + " " + StringHelper.Right("00" + mailSendTime, 2) + ":00");
                settingList.WriteXml(settingFile);
                SaveLog(Resources.OperationSaveSetting, Resources.MsgSaveSettingSuccess);
                return true;
            }
            catch (Exception exeception)
            {
                SaveLog(Resources.OperationSaveSetting, exeception.Message);
                return false;
            }            
        }

        public static bool DetectLogFile()
        {
            var logFound = true;
            var fileInfo = new FileInfo(Resources.LogFileName);

            if (!fileInfo.Exists)
            {
                logFound = CreateLogFile(fileInfo);
                fileInfo.Refresh();
            }

            if(logFound)
                SaveLog(Resources.DectetLogFile, Resources.MsgLogFound);
            else
                SaveLog(Resources.DectetLogFile, Resources.MsgLogMissing);
            return logFound;
        }

        public static bool CreateLogFile(FileInfo fileInfo)
        {
            try
            {
                if (fileInfo == null)
                    return false;

                var streamWriter = fileInfo.CreateText();
                streamWriter.WriteLine(DateTime.Now + " - " + Resources.LogFileHeader);
                streamWriter.Close();
                return true;
            }
            catch (Exception)
            {
                SaveLog(Resources.CreateLogFile, Resources.MsgCreateLogFileFailed);                
            }
            return false;
        }

        public static void SaveLog(string operationInfo, string logInfo)
        {
            var logFound = true;
            var fileInfo = new FileInfo(Resources.LogFileName);
            if (!fileInfo.Exists)
                logFound = CreateLogFile(fileInfo);

            if (!logFound)
                return;

            var streamWriter = new StreamWriter(fileInfo.FullName, true);
            streamWriter.WriteLine(DateTime.Now + " - " + operationInfo + " - " + logInfo);
            streamWriter.Close();
        }
    }
}